package com.ming_za.odupdaterserver.core.controller.web;

import com.ming_za.odupdaterserver.core.config.ConfigManager;
import com.ming_za.odupdaterserver.core.config.type.*;
import com.ming_za.odupdaterserver.core.exception.BusinessException;
import com.ming_za.odupdaterserver.core.exception.ROEnum;
import com.ming_za.odupdaterserver.core.utils.Msg;
import com.ming_za.odupdaterserver.core.utils.VersionUtils;
import com.ming_za.odupdaterserver.core.utils.account.AccountManager;
import com.ming_za.odupdaterserver.core.vo.R;
import com.ming_za.odupdaterserver.core.vo.req.ModifySettingVo;
import com.ming_za.odupdaterserver.core.vo.resp.SettingResp;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;

@Tag(name = "更新器设置相关API")
@RestController
@RequestMapping("/sev-v")
public class ConfigAPI {

    private final ConfigManager configManager;
    private final AccountManager accountManager;

    public ConfigAPI(ConfigManager configManager, AccountManager accountManager) {
        this.configManager = configManager;
        this.accountManager = accountManager;
    }

    @Operation(summary = "设置配置",description = """
            可用的配置名：serverPort(服务器端口)
            | maxDownloadTotalSpeed(最大下载总速率)
            | maxDownloadSpeed(单个通道最大下载速度)
            | maxConcurrentCount(单个ip最大并发量)
            | resFold(资源文件数据存放路径)
            | cache(缓存，优化查询速度)
            | loginVerification(登录验证)
            | allowPasswordErrorCount(允许密码错误尝试次数)
            | verificationLockTime(验证锁定时间)
            | frequentRemoteLock(频繁异地登录锁定)""")
    @PostMapping("/setting")
    public R<?> modifySetting(@RequestBody @Valid ModifySettingVo modifySettingVo){

        if (modifySettingVo.getName().equals("loginVerification") && accountManager.getAllAccount().isEmpty()){
//            throw new BusinessException(ROEnum.USER_ACCOUNT_UNREGISTERED,"首次开启需设置密码");
            return R.pack(ROEnum.USER_ACCOUNT_UNREGISTERED,"首次开启需设置密码");
        }

        ValueType<?> configValueType = getConfigValueType(modifySettingVo.getName());
        if (configValueType instanceof IntValue iv){
            iv.saveValue(Integer.parseInt(modifySettingVo.getValue()));
        }else if (configValueType instanceof BooleanValue bv){
            bv.saveValue(Boolean.parseBoolean(modifySettingVo.getValue()));
        }else if (configValueType instanceof LongValue lv){
            lv.saveValue(Long.parseLong(modifySettingVo.getValue()));
        }else if (configValueType instanceof StringValue sv){
            sv.saveValue(modifySettingVo.getValue());
        }else {
//            throw new BusinessException(ROEnum.SETTING_UNEXPECTED_TYPE);
            return R.pack(ROEnum.SETTING_UNEXPECTED_TYPE);
        }

        return R.ok();
    }

    @Parameters({
            @Parameter(name = "name",description = "配置名，见设置配置接口",in = ParameterIn.PATH,required = true)
    })
    @Operation(summary = "获取配置")
    @GetMapping("/setting/{name}")
    public R<SettingResp> getSetting(@PathVariable("name") String name){
        return R.ok(new SettingResp(String.valueOf(getConfigValueType(name).getValue())));
    }

    private ValueType<?> getConfigValueType(String name){
        return switch (name) {
            case "serverPort" -> configManager.getPort();
            case "maxDownloadTotalSpeed" -> configManager.getMaxDownloadBroadband();
            case "maxDownloadSpeed" -> configManager.getMaxSingleDownloadBroadband();
            case "maxConcurrentCount" -> configManager.getMaxConcurrentDownload();
            case "resFold" -> configManager.getResFold();
            case "cache" -> configManager.getCache();
            case "loginVerification" -> configManager.getLoginVerification();
            case "allowPasswordErrorCount" -> configManager.getAllowPasswordErrorCount();
            case "verificationLockTime" -> configManager.getVerificationLockTime();
            case "frequentRemoteLock" -> configManager.getFrequentRemoteLock();
            default -> throw new BusinessException(ROEnum.SETTING_NOT_FOUND_NAME);
        };

    }

    @Operation(summary = "获取未发布密钥")
    @GetMapping("/unpublishedKey")
    public R<SettingResp> getUnpublishedKey(){
        return R.ok(new SettingResp(String.valueOf(configManager.getUnpublishedSecretKey().getValue())));
    }

    @Operation(summary = "重新生成未发布密钥")
    @PostMapping("/unpublishedKey")
    public R<SettingResp> generateUnpublishedKey(HttpServletRequest request){
        int i = configManager.generateRandomUnpublishedSecretKey();
        Msg.getInstance().info("&e[" + request.getRemoteHost() + "]重新生成未发布密钥。当前密钥：" + i);
        return R.ok(new SettingResp(String.valueOf(i)));
    }
}
